﻿using System;
using System.Collections.Generic;

namespace ChessGameEngine
{
    public abstract class Piece
    {
        protected TilePosition startPosition;
        protected ChessEngine chessEngine;

        protected Piece(ChessEngine chessEngine, object shape, PieceColor color)
        {
            this.chessEngine = chessEngine;
            this.UserInterfaceInstance = shape;
            this.Color = color;
        }

        public bool Moved { get; set;  }
        public TilePosition Position { get; set; }
        public PieceColor Color { get; private set; }
        public object UserInterfaceInstance { get; private set; }

        public virtual IEnumerable<TilePosition> GetAllPossibleMoves()
        {
            return new List<TilePosition>();
        }

        protected IEnumerable<TilePosition> VisitNorthSouthWest(int count)
        {
            if (count != 1) // scan tile only once or all?
                count = ChessEngine.MaxTiles;

            int jSouth = this.Position.J + 1;
            int jNorth = this.Position.J - 1;
            int startIndex = this.Position.I - 1;
            bool pieceNorthWestDetected = false;
            bool pieceSouthWestDetected = false;
            int c = 0;
            for (int iWest = startIndex; iWest >= 0 && c < count; iWest--, jSouth++, jNorth--, c++)
            {
                if (jSouth < ChessEngine.MaxTiles && !pieceSouthWestDetected)
                {
                    var swPos = new TilePosition { I = iWest, J = jSouth };
                    if (chessEngine.IsTileEmpty(swPos))
                    {
                        yield return swPos;
                    }
                    else if (chessEngine.IsOpponent(swPos, this.Color))
                    {
                        pieceSouthWestDetected = true;
                        yield return swPos;
                    }
                    else
                        pieceSouthWestDetected = true;
                }
                if (jNorth >= 0 && !pieceNorthWestDetected)
                {
                    var nwPos = new TilePosition { I = iWest, J = jNorth };
                    if (chessEngine.IsTileEmpty(nwPos))
                    {
                        yield return nwPos;
                    }
                    else if (chessEngine.IsOpponent(nwPos, this.Color))
                    {
                        pieceNorthWestDetected = true;
                        yield return nwPos;
                    }
                    else
                        pieceNorthWestDetected = true;
                }
            }
        }

        protected IEnumerable<TilePosition> VisitNorthSouthEast(int count)
        {
            if (count != 1) // scan one tile only or all?
                count = ChessEngine.MaxTiles;

            int jSouth = this.Position.J + 1;
            int jNorth = this.Position.J - 1;
            bool pieceNorthEastDetected = false;
            bool pieceSouthEastDetected = false;
            int startIndex = this.Position.I + 1;
            int c = 0;
            for (int iEast = startIndex; iEast < ChessEngine.MaxTiles && c < count; iEast++, jSouth++, jNorth--, c++)
            {
                if (jSouth < ChessEngine.MaxTiles && !pieceSouthEastDetected)
                {
                    var sePos = new TilePosition { I = iEast, J = jSouth };
                    if (chessEngine.IsTileEmpty(sePos))
                    {
                        yield return sePos;
                    }
                    else if (chessEngine.IsOpponent(sePos, this.Color))
                    {
                        pieceSouthEastDetected = true;
                        yield return sePos;
                    }
                    else
                        pieceSouthEastDetected = true;
                }
                if (jNorth >= 0 && !pieceNorthEastDetected)
                {
                    var nePos = new TilePosition { I = iEast, J = jNorth };
                    if (chessEngine.IsTileEmpty(nePos))
                    {
                        yield return nePos;
                    }
                    else if (chessEngine.IsOpponent(nePos, this.Color))
                    {
                        pieceNorthEastDetected = true;
                        yield return nePos;
                    }
                    else
                        pieceNorthEastDetected = true;
                }
            }
        }
    }
}